using UnityEngine;
using System.Collections;

public class Split : MonoBehaviour 
{
	public enum Orientation { Horizontal, Vertical};
		
	public Orientation SplitOrientation;	

	public float SplitLocation;
	
	public DungeonBSPNode LeftChild {get; set;}
	public DungeonBSPNode RightChild {get; set;}
	
	static public float SmallestPartitionSize = .2f;
	
	static public float MaxPartitionSizeRatio = 1.5f;
	
	static public float HomogeneityFactor = 0.25f;
		
	public bool RoomBuilt = false;

	public EdgeRect RegionEdges;
	
	public float LeftEdge;
	public float RightEdge;
	public float TopEdge;
	public float BottomEdge;
	
	public float NodeWidth;
	public float NodeHeight;
	
	public Texture2D corridor;
	public Texture2D room;

	// Use this for initialization
	void Start () 
	{
		RegionEdges = FindObjectOfType(typeof(EdgeRect)) as EdgeRect;
	}
	
	// Update is called once per frame
	void Update () 
	{
		
	}
	public void DungeonBSPNode(float startX, float startY, float endX, float endY)
	{
		LeftEdge = RegionEdges.startX;
		RightEdge = RegionEdges.endX;
		TopEdge = RegionEdges.startY;
		BottomEdge = RegionEdges.endY;
		
		NodeWidth = RightEdge - LeftEdge;
		NodeHeight = BottomEdge - TopEdge;
		
	}
	
	public void Partition()
	{
		if (RegionEdges.endX / RegionEdges.endY > MaxPartitionSizeRatio)
			SplitOrientation = Orientation.Horizontal;
		else if (RegionEdges.endY / RegionEdges.endX > MaxPartitionSizeRatio)
			SplitOrientation = Orientation.Vertical;
		else
			SplitOrientation = (Random.value == 1) ? Orientation.Horizontal : Orientation.Vertical;
		
		if (SplitOrientation == Orientation.Horizontal)
		{
			SplitLocation = RegionEdges.startX + HomogenizedRandomValue() * RegionEdges.endX;
			LeftChild = new DungeonBSPNode();
			RightChild = new DungeonBSPNode();

			
			if (WeShouldSplit(SplitLocation - RegionEdges.startX))
				Graphics.DrawTexture(new Rect(SplitLocation, RegionEdges.startY, RegionEdges.endX, RegionEdges.endY), room);
//				LeftChild.Partition();
//			if (WeShouldSplit(RegionEdges.endX - SplitLocation))
//				RightChild.Partition();
           }
		else
		{
			SplitLocation = RegionEdges.startY + HomogenizedRandomValue() * RegionEdges.endY;
			LeftChild = new DungeonBSPNode();
			RightChild = new DungeonBSPNode();
			
			
			if (WeShouldSplit(SplitLocation - RegionEdges.startY))
				Graphics.DrawTexture(new Rect(SplitLocation, RegionEdges.startX, RegionEdges.endX, RegionEdges.endY), room);
//				LeftChild.Partition();
//			if (WeShouldSplit(RegionEdges.endY - SplitLocation))
//				RightChild.Partition();
		}
	}
	
	
/*	public void PartitionAround(Rectangle boundingRect)
	{
		float startX = (float)boundingRect.Left / Map.MapWidth;
        float startY = (float)boundingRect.Top / Map.MapHeight;
        float endX = (float)boundingRect.Right/ Map.MapWidth;
        float endY = (float)boundingRect.Bottom/ Map.MapHeight;

		
        this.SplitOrientation = Orientation.Vertical;
        this.SplitLocation = startX;
        if (startY == RegionEdges.Top)
                LeftChild = null;    
        else
        {
			LeftChild = new dungeonBSPNode(RegionEdges.Left, RegionEdges.Top, RegionEdges.Right, startY);
			if (WeShouldSplit(startY - RegionEdges.Top))
				LeftChild.Partition();
        }
        RightChild = new dungeonBSPNode(RegionEdges.Left, startY, RegionEdges.Right, RegionEdges.Bottom);

        RightChild.SplitOrientation = Orientation.Horizontal;
        RightChild.SplitLocation = startY;
        if (startX == RegionEdges.Left)
                RightChild.LeftChild = null;    
        else
        {
			RightChild.LeftChild = new dungeonBSPNode(RegionEdges.Left, startY, startX, RegionEdges.Bottom);
			if (WeShouldSplit(startX - RegionEdges.Left))
				RightChild.LeftChild.Partition();
        }
        RightChild.RightChild = new dungeonBSPNode(startX, startY, RegionEdges.Right, RegionEdges.Bottom);

        RightChild.RightChild.SplitOrientation = Orientation.Vertical;
        RightChild.RightChild.SplitLocation = endY;
        if (RegionEdges.Bottom == endY)
                RightChild.RightChild.RightChild = null;
        else
        {
			RightChild.RightChild.RightChild = new dungeonBSPNode(startX, endY, RegionEdges.Right, RegionEdges.Bottom);
			if (WeShouldSplit(RegionEdges.Bottom - endY))
				RightChild.RightChild.RightChild.Partition();
        }
        RightChild.RightChild.LeftChild = new dungeonBSPNode(startX, startY, RegionEdges.Right, endY);

        RightChild.RightChild.LeftChild.SplitOrientation = Orientation.Horizontal;
        RightChild.RightChild.LeftChild.SplitLocation = endX;
        if (RegionEdges.Right == endX)
			RightChild.RightChild.LeftChild.RightChild = null;
        else
        {
			RightChild.RightChild.LeftChild.RightChild = new dungeonBSPNode(endX, startY, RegionEdges.Right, endY);
            if (WeShouldSplit(RegionEdges.Right - endX))
				RightChild.RightChild.LeftChild.RightChild.Partition();
        }

        RightChild.RightChild.LeftChild.LeftChild = new dungeonBSPNode(startX, startY, endX, endY);

        RightChild.RightChild.LeftChild.LeftChild.RoomBuilt = true;
        RightChild.RightChild.LeftChild.LeftChild.BoundingRect = boundingRect;
	}*/
	
	private bool WeShouldSplit(float partitionSize)
	{
		if(partitionSize > SmallestPartitionSize && partitionSize < SmallestPartitionSize * 2.0 && Random.value <= .1)
			return false;
		
		return partitionSize > SmallestPartitionSize;
	}
	
	private float HomogenizedRandomValue()
	{
		return (float)(0.5 - (Random.value * HomogeneityFactor));
	}
	
/*	public IList<dungeonBSPNode> GetRoomRegions()
	{
		IList<dungeonBSPNode> list = new IList<dungeonBSPNode>();
		EnumerateLeafNodes(list);
		return list;
	}*/
	
/*	public void EnumerateLeafNodes(IList<dungeonBSPNode> list)
	{
		if(LeftChild != null || RightChild != null)
		{
			if(LeftChild != null)
				LeftChild.EnumerateLeafNodes(list);
			if(RightChild != null)
				RightChild.EnumerateLeafNodes(list);
		}
		else if (RoomBuilt)
			list.Add(this);
	}*/
	
/*	public void BottomsUpByLevelEnumerate(RoomGeneratorDelegate roomGenerator, CorridorGeneratorDelegate corridorGenerator)
	{
		Stack stack1 = new Stack();
        Stack stack2 = new Stack();
        stack1.Push(this);
        while (stack1.Count > 0)
		{
			dungeonBSPNode currentNode = (dungeonBSPNode)stack1.Pop();
            stack2.Push(currentNode);
            if (currentNode.LeftChild != null)
				stack1.Push(currentNode.LeftChild);
            if (currentNode.RightChild != null)
                stack1.Push(currentNode.RightChild);
		}

        while (stack2.Count > 0)
        {
            dungeonBSPNode currentNode = (dungeonBSPNode)stack2.Pop();
            if (currentNode.LeftChild == null && currentNode.RightChild == null)
            {
				// Leaf node - create a room
				if (!currentNode.RoomBuilt && roomGenerator != null)
					roomGenerator(currentNode);
            }
            else
            {
				// non-leaf node; create corridor
				if (corridorGenerator != null && (currentNode.LeftChild.RoomBuilt || currentNode.RightChild.RoomBuilt))
					corridorGenerator(currentNode);
            }
		}
	}*/
}
